package com.jyu.apts.service.impl;

import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.jyu.apts.dao.QRCodeTemplateRepository;
import com.jyu.apts.entity.QRCodeTemplate;
import com.jyu.apts.entityEnum.QRCodeTemplateVisibilityEnum;
import com.jyu.apts.service.QRCodeTemplateService;

@Service
public class QRCodeTemplateServiceImpl implements QRCodeTemplateService {
	
	@Autowired
	QRCodeTemplateRepository qrCodeTemplateDao;
	
	@Override
	public QRCodeTemplate getOne(long id) {
		return qrCodeTemplateDao.findById(id).get();
	}

	@Override
	public Page<QRCodeTemplate> getQRCodeTemplatePage(Integer pageNumber, Integer pageSize, Long organizationId, String search) {
		if(pageNumber == null || pageNumber <= 0) {
			pageNumber = 1;
		}
		if(pageSize == null || pageSize <= 0) {
			pageSize = 10;
		}
		Sort sort = new Sort(Sort.Direction.ASC,"id");
		PageRequest pageRequest = new PageRequest(pageNumber-1,pageSize,sort);
		Specification<QRCodeTemplate> spec = new Specification<QRCodeTemplate>() {
			@Override
			public Predicate toPredicate(Root<QRCodeTemplate> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				Predicate pre = criteriaBuilder.conjunction();
				if(organizationId != null) {
					Predicate or_pre = criteriaBuilder.disjunction();
					or_pre =criteriaBuilder.or(or_pre,criteriaBuilder.equal(root.get("author").get("organization").get("id"), organizationId.longValue()));
					or_pre =criteriaBuilder.or(or_pre,criteriaBuilder.equal(root.get("visibility"),QRCodeTemplateVisibilityEnum.PUBLIC.getType()));
					pre = criteriaBuilder.and(pre,or_pre);
				}
				if(search!=null && search.trim().length()!=0) {
					Predicate or_pre = criteriaBuilder.disjunction();
					or_pre =criteriaBuilder.or(or_pre,criteriaBuilder.like(root.get("name"), "%"+search+"%"));
					or_pre =criteriaBuilder.or(or_pre,criteriaBuilder.like(root.get("description"), "%"+search+"%"));
					or_pre =criteriaBuilder.or(or_pre,criteriaBuilder.like(root.get("dataHeads"), "%"+search+"%"));
					pre = criteriaBuilder.and(pre,or_pre);
				}
				return pre;
			}
			
		};
		return qrCodeTemplateDao.findAll(spec, pageRequest);
	}

	@Override
	public void save(QRCodeTemplate qrCodeTemplate) {
		qrCodeTemplateDao.saveAndFlush(qrCodeTemplate);
	}

	@Override
	public void save(List<QRCodeTemplate> qrCodeTemplates) {
		qrCodeTemplateDao.saveAll(qrCodeTemplates);
		qrCodeTemplateDao.flush();
	}

	@Override
	public void delete(List<QRCodeTemplate> qrCodeTemplates) {
		qrCodeTemplateDao.deleteAll(qrCodeTemplates);
	}

	@Override
	public void delete(QRCodeTemplate qrCodeTemplate) {
		qrCodeTemplateDao.delete(qrCodeTemplate);
	}

	@Override
	public List<QRCodeTemplate> findAll() {
		return qrCodeTemplateDao.findAll();
	}

	@Override
	public List<QRCodeTemplate> findAllById(List<Long> ids) {
		return qrCodeTemplateDao.findAllById(ids);
	}

	@Override
	public List<QRCodeTemplate> findAllByOrganization(long organizationId) {
		Sort sort = new Sort(Sort.Direction.ASC,"id");
		Specification<QRCodeTemplate> spec = new Specification<QRCodeTemplate>() {
			@Override
			public Predicate toPredicate(Root<QRCodeTemplate> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				Predicate pre = criteriaBuilder.conjunction();
				Predicate or_pre = criteriaBuilder.disjunction();
				or_pre =criteriaBuilder.or(or_pre,criteriaBuilder.equal(root.get("author").get("organization").get("id"), organizationId));
				or_pre =criteriaBuilder.or(or_pre,criteriaBuilder.equal(root.get("visibility"),QRCodeTemplateVisibilityEnum.PUBLIC.getType()));
				pre = criteriaBuilder.and(pre,or_pre);
				return pre;
			}
			
		};
		return qrCodeTemplateDao.findAll(spec,sort);
	}

}
